/*
打印
 */
import 'package:reabampos/src/reabam/operation/bean/h5_print.dart';
import 'package:reabampos/src/reabam/operation/rb_api.dart';
import 'package:reabampos/src/reabam/operation/rb_config.dart';
import 'package:reabampos/src/reabam/ui/pagestate_main_webview.dart';
import 'package:reabampos/src/reabam/ui/setting/bean/bean_appoint_printer_scene.dart';
import 'package:reabampos/src/reabam/utils/rb_aliyun_log.dart';
import 'package:xsdk_flutter/xsdk/utils/x_utils_aliyun_log.dart';
import 'package:xsdk_flutter/xsdk/xsdk_flutter_package.dart';
import 'package:xsdk_flutter_plugin/xsdk_flutter_plugin.dart';

abstract class SupportControlDevices {

  static XQueue? msgQueue;

  //1.初始化
  static void init(XPageState statePage) {
    //初始化h5打印通知队列
    _initH5PrintMsgQueue(statePage);
    //蓝牙BLE设备监听
    _initBleDeviceListener(statePage);
    //Socket设备监听
    _initSocketDeviceListener(statePage);
  }

//////////////////////////////////////////////

  static List<XBaseDevice> bluetoothPrinters=[];
  static List<XBaseDevice> socketPrinters_ip=[];
  static List<XBaseDevice> cloudPrinters=[];
  static List<XBaseDevice> usbPrinters=[];
  static XBaseDevice? bluetoothWeigher;
  static XBaseDevice? usbWeigher;
  //叫号屏
  static XBaseDevice? socketTV;
  static XBaseDevice? clientSocketPrinter;

  //是否启用多端打印
  static bool isEnableServerClientSocketPrint=false;
  //是否多端打印服务端
  static bool isServerSocketPrinter=false;

  //设备设置指定打印机
  static List<BeanAppointPrinterScene> appointPrinterSettingList=[];


  //1.初始化或重新初始化(外界)
  static void initAllDevicesNoteSetting(){
    try{
      socketTV=null;
      clientSocketPrinter=null;
      usbWeigher=null;
      bluetoothWeigher=null;
      bluetoothPrinters.clear();
      socketPrinters_ip.clear();
      cloudPrinters.clear();
      usbPrinters.clear();
      appointPrinterSettingList.clear();

      //蓝牙
      for(XBaseDevice device in XBluetoothBLEUtils.bluetoothBLEDeviceList){
        if(RBConfigs.BluetoothPrinter==device.customType){
          bluetoothPrinters.add(device);
        }else if(RBConfigs.BluetoothWeigher==device.customType){
          bluetoothWeigher=device;
        }
      }

      //网络
      for(XBaseDevice device in XSocketUtils.socketDeviceList){
        if(RBConfigs.SocketTV==device.customType){
          socketTV=device;
        }else if(RBConfigs.IPPrinter==device.customType){
          socketPrinters_ip.add(device);
        }else if(RBConfigs.ClientSocketPrinter==device.customType){
          clientSocketPrinter=device;
        }
      }

      //快麦云打印
      for(XBaseDevice device in XRemoteDeviceUtils.remoteDeviceList){
        cloudPrinters.add(device);
      }

      //usb
      for(XBaseDevice device in XUsbUtils.usbDeviceList){
        if(RBConfigs.USBPrinter==device.customType){
          usbPrinters.add(device);
        }
      }


      //多端打印
      isEnableServerClientSocketPrint=false;
      isServerSocketPrinter=false;
      //
      String companyId=XSharePreferencesUtils.getString(RBConfigs.SP_companyId);
      bool isUseServerClientSocketPrinter=XSharePreferencesUtils.getBool('${RBConfigs.SP_isUseServerClientSocketPrinter}$companyId');
      String currentSocketServerOrClient=XSharePreferencesUtils.getString('${RBConfigs.SP_currentServerOrClientSoscketPrinter}$companyId');
      if(isUseServerClientSocketPrinter){
        if(currentSocketServerOrClient=='主设备'){
          isEnableServerClientSocketPrint=true;
          isServerSocketPrinter=true;
        }else if(currentSocketServerOrClient=='子设备'){
          isEnableServerClientSocketPrint=true;
        }
      }

      //
      if(isEnableServerClientSocketPrint){
        String json_appointPrinterSettingList='';
        if(isServerSocketPrinter){
          json_appointPrinterSettingList=XSharePreferencesUtils.getString('${RBConfigs.SP_ServerSocket_Appoint_printer}$companyId');
        }else{
          json_appointPrinterSettingList=XSharePreferencesUtils.getString('${RBConfigs.SP_ClientSocket_Appoint_printer}$companyId');
        }

        if (!XStringUtils.isEmpty(json_appointPrinterSettingList)){
          List<dynamic> ll=XJsonUtils.json2List(json_appointPrinterSettingList);
          for(dynamic item in ll){
            appointPrinterSettingList.add(BeanAppointPrinterScene.fromJson(item));
          }
        }

      }

    }catch(e){
      XLogUtils.printLog('---initAllDevicesNoteSetting error: $e');
    }
  }

  //收到h5通知打印ok
  static void needPrint(XPageState statePage,dynamic data){
    //注意: 如果收不到h5通知,则检测门店是否开启在线打印
    try{
      BeanH5PrintInfo beanH5PrintInfo;
      if(data is String){
        beanH5PrintInfo=BeanH5PrintInfo.fromJson(XJsonUtils.json2Map(data));
      }else{
        beanH5PrintInfo=BeanH5PrintInfo.fromJson(data);
      }

      XLogUtils.printLog('---收到h5通知打印needPrint, kmPrintH5Id=${beanH5PrintInfo.kmPrintH5Id}, 设备场景printerTag:${beanH5PrintInfo.printerTag}, 设备序号printIndex:${beanH5PrintInfo.printIndex}, beanH5PrintInfo=${XJsonUtils.obj2Json(beanH5PrintInfo)}');
      //日志
      XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(beanH5PrintInfo.orderNo), '收到h5通知打印: 设备场景printerTag=${beanH5PrintInfo.printerTag}, 设备序号printIndex=${beanH5PrintInfo.printIndex}, kmPrintH5Id=${beanH5PrintInfo.kmPrintH5Id}, data= $data');

      // hyl 2021.11.25 不需要本地做重打漏打机制,交给服务端
      String createTime=XDateUtils.getCurrentTime_String(format: XDateUtils.formatTimeDefault2);
      String msgId='${beanH5PrintInfo.orderNo}_${beanH5PrintInfo.kmPrintH5Id??XDateUtils.getCurrentTime_ms()}';

      beanH5PrintInfo.kmItemsId??='10';
      beanH5PrintInfo.kmUserId??='13826056942';
      beanH5PrintInfo.kmPrintH5Id??='kmPrintH5Id=null';

      XBaseQueueMessage printMsg=XBaseQueueMessage(
        msgId: msgId,
        isSaveToQueueSrcMsgList:true,
        createTime: createTime,
        message: beanH5PrintInfo.printDataJson??'',
        orderId:beanH5PrintInfo.orderId,
        orderNo:beanH5PrintInfo.orderNo,
        orderType:'${beanH5PrintInfo.orderType}',
        templateId:beanH5PrintInfo.kmId,
        templateType:beanH5PrintInfo.kmCmdType,
        otherParams: [
          '${beanH5PrintInfo.kmItemsId}',
          '${beanH5PrintInfo.kmUserId}',
          '${beanH5PrintInfo.kmPrintH5Id}',
        ],
      );

      //打印场景
      if(beanH5PrintInfo.printerTag==null){
        //日志
        XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(beanH5PrintInfo.orderNo), 'h5打印内容没有设置打印场景');
        //通知h5,-2没有找到打印机
        _printResult_callback_H5_or_clientSocket(statePage,false,'没有设置打印场景',printMsg);
        return;
      }

      XBaseDeviceScene deviceScene=XBaseDeviceScene(id: '${beanH5PrintInfo.printerTag}');
      printMsg.deviceScene=deviceScene;

      //判断是否有蓝牙打印设备
      if(RBConfigs.isShangMiDevice && RBConfigs.isUserShangMiPrint && '${beanH5PrintInfo.printerTag}'!="4"){
        //商米设备,小票打印,不需要判断 ok  保存到队列
        XLogUtils.printLog('---商米设备,小票打印,不需要判断 ok');

        msgQueue?.addNewMsgToQueueForWaitQueueAutoHandle(printMsg);
        return;
      }

      if(bluetoothPrinters.isEmpty
          && usbPrinters.isEmpty
          && socketPrinters_ip.isEmpty
          && cloudPrinters.isEmpty
          && (!isEnableServerClientSocketPrint || isServerSocketPrinter)
      ){
        XLogUtils.printLog('---设备没有设置打印机!');
        //阿里云日志
        XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(beanH5PrintInfo.orderNo),"设备没有设置打印机!");
        statePage.toast("请先设置打印机");
        //通知h5,-2没有找到打印机
        _printResult_callback_H5_or_clientSocket(statePage,false,'没有设置打印机',printMsg);
        return;
      }

      //是否多端子设备打印
      if(isEnableServerClientSocketPrint && !isServerSocketPrinter){
        //阿里云日志
        XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(beanH5PrintInfo.orderNo),"开启多端打印,子设备...");
      }

      //打印序号
      if(beanH5PrintInfo.printIndex!=null){
        //以h5指定打印机序号优先
        printMsg.deviceSerialNumber='${beanH5PrintInfo.printIndex}';
      }

      //h5没有指定打印机序号
      if(XStringUtils.isEmpty(printMsg.deviceSerialNumber)){
        //开启多端打印,以指定打印机设置为准
        if(isEnableServerClientSocketPrint && appointPrinterSettingList.isNotEmpty){
          List<String> deviceSerialNumbers=[];
          for(BeanAppointPrinterScene appointPrinterScene in appointPrinterSettingList){
            if('${beanH5PrintInfo.printerTag}'==appointPrinterScene.id){
              List<BeanAppointPrinterIndex> printerIndexs=appointPrinterScene.printerIndexs;
              for(BeanAppointPrinterIndex appointPrinterIndex in printerIndexs){
                if(appointPrinterIndex.isUserSelect){
                  deviceSerialNumbers.add(appointPrinterIndex.id);
                }
              }
              break;
            }
          }

          //拆分多条打印
          if(deviceSerialNumbers.length!=0){
            XLogUtils.printLog('---多端打印,指定设置打印机序号,deviceSerialNumbers=${deviceSerialNumbers.length},${XJsonUtils.obj2Json(deviceSerialNumbers)}');
            //阿里云日志
            XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(beanH5PrintInfo.orderNo),"---多端打印,指定设置打印机序号,deviceSerialNumbers=${XJsonUtils.obj2Json(deviceSerialNumbers)}");

            String mJson=XJsonUtils.obj2Json(printMsg);
            for(int i=0;i<deviceSerialNumbers.length;i++){
              XLogUtils.printLog('---多端打印,for指定设置打印机序号,i=$i,${deviceSerialNumbers[i]}');
              XBaseQueueMessage nMsg=XBaseQueueMessage.fromJson(XJsonUtils.json2Map(mJson));
              nMsg.msgId='拆分${i}_${nMsg.msgId}';
              nMsg.deviceSerialNumber=deviceSerialNumbers[i];
              msgQueue?.addNewMsgToQueueForWaitQueueAutoHandle(nMsg);
            }
            return;
          }
        }
      }

      //默认1号设备
      if(XStringUtils.isEmpty(printMsg.deviceSerialNumber)){
        printMsg.deviceSerialNumber='1';
      }
      //
      msgQueue?.addNewMsgToQueueForWaitQueueAutoHandle(printMsg);

    }catch(e){
      XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_trycache('needPrint'),'$e');
      XLogUtils.printLog('$e');
    }

  }

  //初始化h5打印通知队列
  static void _initH5PrintMsgQueue(XPageState statePage){
    if(msgQueue!=null){
      msgQueue?.xRelease();
      msgQueue=null;
    }

    msgQueue=XQueue(
        queueName: 'H5PrintMsgQueue',
        isConcurrentMode: true,
        notifyHandleMsg: (XBaseQueueMessage msg) {

          //子设备以主设备的打印配置为准
          if(isEnableServerClientSocketPrint && !isServerSocketPrinter){
            //开启多端打印,子设备发送打印消息到主设备
            if(clientSocketPrinter!=null && clientSocketPrinter!.isConnected){
              //
              XLogUtils.printLog('---多端打印,子设备正在发送打印,msg=${msg.msgId}');
              //阿里云日志
              XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo), '---多端打印,子设备正在发送打印,msg=${msg.msgId}');
              //
              Map<String,dynamic> socketMap={};
              socketMap['type']='XClientSocketPrint';
              socketMap['data']=msg;
              //
              XBaseQueueMessage socketMsg=XBaseQueueMessage(
                msgId: msg.msgId,
                message: socketMap,
                ip:clientSocketPrinter!.ip,
                port:clientSocketPrinter!.port,
              );
              XSocketUtils.sendMsgToQueue(socketMsg);


            }else{
              XLogUtils.printLog('---多端打印,子设备已断开连接,发送打印失败');
              //阿里云日志
              XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo), '---多端打印,子设备已断开连接,发送打印失败');
              //打印结果通知h5
              _printResult_callback_H5_or_clientSocket(statePage,false,clientSocketPrinter?.ip??'',msg);
            }

            return;
          }

          //1.优先使用云打印
          bool isUseKuaimaiCloudPrint=_use_cloud_print(statePage,msg);
          if (isUseKuaimaiCloudPrint){
            return;
          }
          //2.使用快麦api在线模板生成打印命令,本地连接蓝牙,网络,usb设备打印
          _use_ble_socket_usb_print(statePage,msg);

        },
        notifyTempMsgQueueIdleAndMsgQueueHasItem: () {

        },
        notifyHandleHeartbeat: () {
          //没有心跳包,不需要处理
        }
    );
    msgQueue!.init();

  }

  //1.使用云打印
  static bool _use_cloud_print(XPageState statePage,XBaseQueueMessage tempMsg){

      //判断是否存在指定打印机序号
      String? deviceSerialNumber=tempMsg.deviceSerialNumber;
      //hyl 2023.10.28 优化, 必定存在打印机序号,默认1,
      XBaseDevice? appointPrinter;
      for (XBaseDevice deviceItem in cloudPrinters){
        //判断设备序号
        if (deviceSerialNumber==deviceItem.serialNumber){
          List<XBaseDeviceScene>? scenes=deviceItem.scenes;
          if (scenes!=null){
            for (XBaseDeviceScene scene in scenes){
              //判断设备场景
              if (scene == tempMsg.deviceScene){
                appointPrinter=deviceItem;
                //
                break;
              }
            }
            if(appointPrinter!=null){
              break;
            }
          }
        }
      }


      //
      if(appointPrinter!=null){
        XLogUtils.printLog("---找到指定云打印机");

        int templateType=0;
        if (XStringUtils.equalsIgnoreCase('getTicketData', tempMsg.templateType)) {
          templateType=0;//小票
        }else{
          templateType=1;//标签
        }

        if('快麦'==appointPrinter.brand){
          RBBaseApi.useKuaimaiCloudDevicePrint(
              requestId: tempMsg.msgId,
              dataSet: XJsonUtils.json2Map(tempMsg.message),
              sn: appointPrinter.deviceUUID,
              templateId: tempMsg.templateId,
              type:templateType,
              succeed: (response, Map<String, dynamic> responseMap, Map<String, dynamic> headers_response) {
                //处理消息队列
                msgQueue?.handleSucceedMessageAndUnLockTempMessageQueue(responseMap['data']?['requestId']);
                //打印结果通知
                _printResult_callback_H5_or_clientSocket(statePage,true,'云打印:${appointPrinter!.brand}',tempMsg);
              },
              failed: (String code, String msg) {
                //处理消息队列
                msgQueue?.handleFailedMessageAndUnlockTempMessageQueue(tempMsg.msgId, msg);
                //打印结果通知
                _printResult_callback_H5_or_clientSocket(statePage,false,'云打印:${appointPrinter!.brand}',tempMsg);

              }
          );

        }else{
          //其他品牌调用api打印...
          //处理消息队列
          msgQueue?.handleFailedMessageAndUnlockTempMessageQueue(tempMsg.msgId, '使用云打印失败,没有配置该品牌${appointPrinter.brand}云打印api');
          //打印结果通知
          _printResult_callback_H5_or_clientSocket(statePage,false,'云打印:${appointPrinter.brand}',tempMsg);
        }

        return true;
      }



    //没有可用的云打印
    return false;
  }

  //2.使用蓝牙,socket,usb打印
  static void _use_ble_socket_usb_print(XPageState statePage,XBaseQueueMessage msg){

    //请求快麦打印
    XLogUtils.printLog('---发起请求快麦api,orderNo=${msg.orderNo}, msgId=${msg.msgId}, data=${msg.message}');
    //日志
    XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo), '---发起请求快麦api, msgId=${msg.msgId}, 类型=${msg.templateType} data=${msg.message}');

    if (XStringUtils.equalsIgnoreCase('getTicketData', msg.templateType)){
      //小票打印ok
      XLogUtils.printLog('---快麦小票打印');
      //
      RBBaseApi.kmXiaopiaoPrint(
          templateId: msg.templateId??'',
          renderData: msg.message??'',
          requestId: msg.msgId??'',
          succeed: (dynamic response1, Map<String, dynamic> responseMap, Map<String, dynamic> headersResponse) {

            Future((){
              //
              XLogUtils.printLog('---快麦小票打印api请求返回成功! msgId=${responseMap['requestId']}, response=${responseMap['data']}');
              //阿里云日志
              XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo), '---快麦小票打印api请求成功,返回: msgId=${responseMap['requestId']}, response=${responseMap['data']}');
              //成功,处理消息队列,并获得留底消息
              XBaseQueueMessage? msgSrc= msgQueue?.handleSucceedMessageAndUnLockTempMessageQueue(responseMap['requestId']);

              if(msgSrc!=null){
                // hyl 2021.11.25 打印机队列不需要留底
                msgSrc.isSaveToQueueSrcMsgList=false;
                XLogUtils.printLog('---找到对应的消息,处理快麦小票api响应');
                //阿里云日志
                XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo), '---找到对应的消息,处理快麦小票api响应');
                //处理快麦小票api响应
                _handleKMResponse_xiaopiao(statePage,responseMap,msgSrc);
              }else{
                XLogUtils.printLog('---找不到对应的消息,返回的requestId= ${responseMap['requestId']} 不能匹配');
                //阿里云日志
                XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo), '---找不到对应的原始消息,返回的requestId= ${responseMap['requestId']} 不能匹配');
                //这里找不到原始消息,无法通知h5,等h5超时再重发
              }
            });

          },
          failed: (String code, String errorMsg) {
            XLogUtils.printLog('---快麦小票请求api失败!');
            statePage.toast('快麦小票请求api失败!');
            //阿里云日志
            XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo), '---快麦小票打印api请求失败! msgId=${msg.msgId}, errorMsg=$errorMsg');
            //
            msgQueue?.handleFailedMessageAndUnlockTempMessageQueue(msg.msgId, errorMsg);
            //通知h5
            _printResult_callback_H5_or_clientSocket(statePage,false,'快麦小票请求api失败',msg);
          }
      );
    }else{
      //标签打印ok
      XLogUtils.printLog('---快麦标签打印');
      RBBaseApi.kmTSPLPrint(
          templateId: msg.templateId??'',
          renderData: msg.message??'',
          requestId: msg.msgId??'',
          succeed: (dynamic response1, Map<String, dynamic> responseMap, Map<String, dynamic> headersResponse) {

            Future((){
//
              XLogUtils.printLog('---快麦标签打印api请求成功,返回: msgId=${responseMap['requestId']}, response=${responseMap['data']}');
              //阿里云日志
              XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo), '---快麦标签打印api请求成功,返回: msgId=${responseMap['requestId']}, response=${responseMap['data']}');
              //成功,处理消息队列,并获得留底消息
              XBaseQueueMessage? msgSrc= msgQueue?.handleSucceedMessageAndUnLockTempMessageQueue(responseMap['requestId']);

              if(msgSrc!=null){
                // hyl 2021.11.25 打印机队列不需要留底
                msgSrc.isSaveToQueueSrcMsgList=false;
                XLogUtils.printLog('---找到对应的消息,处理快麦标签api响应');
                //阿里云日志
                XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo), '---找到对应的消息,处理快麦标签api响应');
                //处理快麦标签api响应
                _handleKMResponse_biaoqian(statePage,responseMap,msgSrc);
              }else{
                XLogUtils.printLog('---找不到对应的消息,返回的requestId= ${responseMap['requestId']} 不能匹配');
                //阿里云日志
                XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo), '---找不到对应的消息,返回的requestId= ${responseMap['requestId']} 不能匹配');
              }
            });

          },
          failed: (String code, String errorMsg) {
            XLogUtils.printLog('--快麦标签打印api请求失败');
            statePage.toast('快麦标签打印api请求失败!');
            //阿里云日志
            XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo), '---快麦标签打印api请求失败! msgId=${msg.msgId}, errorMsg=$errorMsg');
            //
            msgQueue?.handleFailedMessageAndUnlockTempMessageQueue(msg.msgId, errorMsg);
            //通知h5
            _printResult_callback_H5_or_clientSocket(statePage,false,'快麦标签打印api请求失败',msg);
          }
      );
    }
  }

  //处理快麦小票api响应
  static void _handleKMResponse_xiaopiao(XPageState statePage,Map<String, dynamic> responseMap,XBaseQueueMessage msgSrc){

    //小票模版数据 base64转字节流
    List<int> dataByte=XJiamiUtils.base64ToUint8List(responseMap['data']??'');

    if(RBConfigs.isShangMiDevice && RBConfigs.isUserShangMiPrint){
      //商米内置打印
      XFlutterPluginUtils.printBytesByShangMi(dataByte);
      //通知h5
      _printResult_callback_H5_or_clientSocket(statePage,true,'商米内置打印',msgSrc);

    }else{
      //蓝牙小票打印机
      msgSrc.message_Uint8List=dataByte;

      XLogUtils.printLog('---蓝牙/usb/网络设备开始打印小票...');
      //阿里云日志
      XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(msgSrc.orderNo), '蓝牙/usb/网络设备开始打印小票...');

      //蓝牙/usb/网络设备打印
      _printWithBleSocketUSB(statePage,msgSrc,'小票');

    }
  }

  //处理快麦标签api响应
  static void _handleKMResponse_biaoqian(XPageState statePage,Map<String, dynamic> responseMap,XBaseQueueMessage msgSrc){

    XLogUtils.printLog('---蓝牙/usb/网络设备开始打印标签...');
    //阿里云日志
    XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(msgSrc.orderNo), '蓝牙/usb/网络设备开始打印标签...');

    //小票模版数据 base64转字节流
    List<int> dataByte=XJiamiUtils.base64ToUint8List(responseMap['data']??'');
    msgSrc.message_Uint8List=dataByte;

    //蓝牙/usb/网络设备打印
    _printWithBleSocketUSB(statePage,msgSrc,'标签');

  }

  //蓝牙/usb/网络设备打印
  static void _printWithBleSocketUSB(XPageState statePage,XBaseQueueMessage msgSrc,String printTagName){

    //判断是否存在指定打印机序号(采用确定蓝牙地址方式)
    String? deviceSerialNumber=msgSrc.deviceSerialNumber;
    //hyl 2023.10.28 优化, 必定存在打印机序号,默认1,
    bool isHasAppointPrinter=false;
    //确定蓝牙地址
    for (XBaseDevice deviceItem in bluetoothPrinters){
      //判断设备序号
      if (deviceSerialNumber==deviceItem.serialNumber){
        List<XBaseDeviceScene>? scenes=deviceItem.scenes;
        if (scenes!=null){
          for (XBaseDeviceScene scene in scenes){
            //判断设备场景
            if (scene == msgSrc.deviceScene){
              //
              isHasAppointPrinter=true;
              //
              msgSrc.deviceName=deviceItem.deviceName;
              msgSrc.bluetoothAddress=deviceItem.bluetoothAddress;
              //
              XBluetoothBLEUtils.sendMsgToQueue(msgSrc);
              break;
            }
          }
        }
      }
    }

    if(isHasAppointPrinter){
      XLogUtils.printLog("---已找到指定蓝牙打印机,$printTagName打印");
      //阿里云日志
      XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(msgSrc.orderNo), '---已找到指定蓝牙打印机,$printTagName打印');
      return;
    }

    //ip打印机
    for (XBaseDevice deviceItem in socketPrinters_ip){
      //判断设备序号
      if (deviceSerialNumber==deviceItem.serialNumber){
        List<XBaseDeviceScene>? scenes=deviceItem.scenes;
        if (scenes!=null){
          for (XBaseDeviceScene scene in scenes){
            //判断设备场景
            if (scene==msgSrc.deviceScene){
              //
              isHasAppointPrinter=true;
              //
              msgSrc.deviceName=deviceItem.deviceName;
              msgSrc.ip=deviceItem.ip;//"192.168.2.111";
              msgSrc.port=deviceItem.port;//9100;
              XSocketUtils.sendMsgToQueue(msgSrc);
              break;
            }
          }
        }
      }
    }

    if(isHasAppointPrinter){
      XLogUtils.printLog("---已找到指定IP打印机,打印$printTagName");
      //阿里云日志
      XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(msgSrc.orderNo), '---已找到指定IP打印机,打印$printTagName');
      return;
    }

    for (XBaseDevice deviceItem in usbPrinters){
      //判断设备序号
      if (deviceSerialNumber==deviceItem.serialNumber){
        List<XBaseDeviceScene>? scenes=deviceItem.scenes;
        if (scenes!=null){
          for (XBaseDeviceScene scene in scenes){
            //判断设备场景
            if (scene==msgSrc.deviceScene){
              //
              isHasAppointPrinter=true;
              msgSrc.deviceName=deviceItem.deviceName;
              //
              XUsbUtils.sendMessage(
                  deviceItem,
                  msgSrc
              ).then((bool isSuccess){

                if (XStringUtils.isEmpty(msgSrc.orderNo)) {
                  //测试打印,忽略不通知h5
                  return;
                }

                //打印结果通知
                _printResult_callback_H5_or_clientSocket(statePage,isSuccess,deviceItem.deviceName??'',msgSrc);

              });
              break;

            }
          }
        }
      }
    }

    if(isHasAppointPrinter){
      XLogUtils.printLog("---已找到指定USB打印机,打印$printTagName");
      //阿里云日志
      XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(msgSrc.orderNo), '---已找到指定USB打印机,打印$printTagName');
      return;
    }

    if (!isHasAppointPrinter){
      XLogUtils.printLog("---没有找到指定$printTagName打印机");
      //阿里云日志
      XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(msgSrc.orderNo), '---没有找到指定$printTagName打印机');

      //打印结果通知
      _printResult_callback_H5_or_clientSocket(statePage,false,'没有找到指定打印机',msgSrc);

    }

  }

  //打印结果通知h5
  static void _printResult_callback_H5_or_clientSocket(XPageState statePage,bool isPrintSuccess,String deviceName,XBaseQueueMessage? msg){

    dynamic kmPrintH5Id = "";
    try {
      List<dynamic>? parmList = msg?.otherParams;
      if (parmList!=null) {
        if (parmList.length >2) {
          kmPrintH5Id = parmList[2];
        }
      }
    } catch (e) {
      XLogUtils.printLog('---otherParams报错: error:$e');
    }



    if(msg!=null && msg.isRemoteSocketMessage==true){
      //通知clientSocket
      XLogUtils.printLog('---打印设备:$deviceName, ${isPrintSuccess?"打印成功":"打印失败"},通知子设备,msg=${msg.msgId}');
      //阿里云日志
      XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo), '---打印设备:$deviceName, ${isPrintSuccess?"打印成功":"打印失败"},通知子设备,kmPrintH5Id=$kmPrintH5Id, msgId=${msg.msgId}');


      msg.message_Uint8List=null;
      msg.message=null;
      msg.isRemoteSocketMessage=false;

      Map<String,dynamic> dMap={};
      dMap['type']='ServerSocketNotifyClientSocketWriteMsgResult';
      dMap['isPrintSuccess']=isPrintSuccess;
      dMap['data']=msg;

      XBaseQueueMessage msgSocket=XBaseQueueMessage(
          msgId: '通知子设备_${XDateUtils.getCurrentTime_ms()}',
          isServerSendToClientMessage: true,
          ip: msg.remoteIP,
          port: msg.remotePort,
          message: dMap
      );
      XSocketUtils.sendMsgToQueue(msgSocket);

    }else{
      //通知h5
      XLogUtils.printLog('---打印设备:$deviceName, ${isPrintSuccess?"打印成功":"打印失败"},通知h5,kmPrintH5Id=$kmPrintH5Id');
      //阿里云日志
      XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(msg?.orderNo), '---打印设备:$deviceName, ${isPrintSuccess?"打印成功":"打印失败"},通知h5,kmPrintH5Id=$kmPrintH5Id');

      if (isPrintSuccess) {
        //打印成功
        if(statePage is MainWebViewStatePage){
          statePage.runJSFunction(_jsFunction_notifyPrintEnd('1', kmPrintH5Id));
        }

      } else {
        //打印失败
        statePage.toast('打印设备:$deviceName 打印失败!');
        if(statePage is MainWebViewStatePage){
          statePage.runJSFunction(_jsFunction_notifyPrintEnd('-1', kmPrintH5Id));
        }
      }

    }

  }

  //////////////////////////////

//写入蓝牙BLE设备监听
  static XFunctionWriteMessageToBleDeviceListener? writeMessageToBleDeviceListener;
  static XFunctionBleDeviceConnectListener? bleDeviceConnectListener;
  //蓝牙监听
  static void _initBleDeviceListener(XPageState statePage){
    //写入蓝牙BLE设备监听
    writeMessageToBleDeviceListener =
        (isSuccess, deviceName, deviceAddress, msg) {
      if (msg==null || XStringUtils.isEmpty(msg.orderNo)) {
        //测试打印,忽略不通知h5
        XLogUtils.printLog('---orderNo=null,忽略不通知h5');
        return;
      }

      //
      _printResult_callback_H5_or_clientSocket(statePage,isSuccess,deviceName??'',msg);

    };
    bleDeviceConnectListener=(bool isConnect,String deviceAddress){
      if(!isConnect){
        statePage.toast('蓝牙设备:$deviceAddress 断开连接');
      }
    };

    //
    XBluetoothBLEUtils.addWriteMessageToBleDeviceListener(writeMessageToBleDeviceListener!);
    XBluetoothBLEUtils.addBleDeviceConnectListener(bleDeviceConnectListener!);
  }

  //
  static XFunctionReceiveSocketDeviceMessageListener? serverSocketDeviceReceiveMessageListener;
  static XFunctionReceiveSocketDeviceMessageListener? clientSocketDeviceReceiveMessageListener;
  static XFunctionWriteMessageToSocketDeviceListener? serverSocketWriteMessageListener;
  static XFunctionWriteMessageToSocketDeviceListener? clientSocketWriteMessageListener;
  static XFunctionClientSocketDeviceConnectListener? clientSocketDeviceConnectListener;
  //socket设备监听
  static void _initSocketDeviceListener(XPageState statePage){
    //接收监听
    serverSocketDeviceReceiveMessageListener =
        (
        String? ip,//对方ip
        int? port,//对方端口
        String? message) {
      //服务端
      //XLogUtils.printLog('---hd服务端接收到消息: ip=$ip, message=$message');
      try {
        if(message!=null && message.startsWith('{')){
          Map<String,dynamic> socketMap=XJsonUtils.json2Map(message);

          if('XCustomSocketData'==socketMap['XDataType']){
            //XLogUtils.printLog('---hd主设备收到自定义socket通讯消息: ip=$ip, port=$port, message=$message');
            //
            Map<String,dynamic> xData=socketMap['XData']??{};

            //
            if('XClientSocketTestPrint'==xData['type']){
              //测试
              statePage.toast('多端打印子设备:$ip 测试');
              XTTSUtils.speak('多端打印子设备测试');
            }else if('XClientSocketPrint'==xData['type']){
              //子设备发送到主设备打印
              XBaseQueueMessage? msg=XBaseQueueMessage.fromJson(xData['data']);
              msg.isRemoteSocketMessage=true;
              msg.isSaveToQueueSrcMsgList=true;
              msg.remoteIP=ip;
              msg.remotePort=port??10000;
              XLogUtils.printLog('---hd主设备收到子设备打印通知,msgId=${msg.msgId}');
              //阿里云日志
              XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(msg.orderNo), '---hd主设备收到子设备打印通知:$message,ip=$ip,port=$port');


              //
              msgQueue?.addNewMsgToQueueForWaitQueueAutoHandle(msg);

            }

          }

        }

      }catch (e) {
        XLogUtils.printLog('---serverSocketDeviceReceiveMessageListener, error:$e');
      }
    };
    clientSocketDeviceReceiveMessageListener =
        (
        String? ip,//对方ip
        int? port,//对方端口
        String? message) {

      //客户端
      //XLogUtils.printLog('---hd客户端接收到消息: ip=$ip,port=$port,message=$message');

      try {
        if(message!=null && message.startsWith('{')){
          Map<String,dynamic> socketMap=XJsonUtils.json2Map(message);

          if('XCustomSocketData'==socketMap['XDataType']){
            Map<String,dynamic> xData=socketMap['XData']??{};

            if('ServerSocketNotifyClientSocketWriteMsgResult'==xData['type']){
              XLogUtils.printLog('---hd客户端收到自定义消息: ip=$ip, port=$port, message=$message');
              //子设备发送到主设备打印
              XBaseQueueMessage? msg=XBaseQueueMessage.fromJson(xData['data']);
              msg.isRemoteSocketMessage=false;
              bool isPrintSuccess=xData['isPrintSuccess'];
              _printResult_callback_H5_or_clientSocket(statePage,isPrintSuccess,'子设备',msg);
            }
          }

        }

      }catch (e) {
        XLogUtils.printLog('---serverSocketDeviceReceiveMessageListener, error:$e');
      }
    };
    //
    XSocketUtils.addServerSocketDeviceReceiveMessageListener(serverSocketDeviceReceiveMessageListener);
    XSocketUtils.addClientSocketDeviceReceiveMessageListener(clientSocketDeviceReceiveMessageListener);

    //写入监听
    serverSocketWriteMessageListener=(
        bool isSuccess,
        String? ip,
        XBaseQueueMessage? msg
        ){
      //打印结果通
      XLogUtils.printLog('---HD服务端写入结果:isSuccess=$isSuccess,ip=$ip,msgId=${msg?.msgId}');
      //阿里云日志
      XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(msg?.orderNo), '---HD服务端写入结果:isSuccess=$isSuccess,ip=$ip,msgId=${msg?.msgId}');

    };
    clientSocketWriteMessageListener=(
        bool isSuccess,
        String? ip,
        XBaseQueueMessage? msg
        ){
      //
      XLogUtils.printLog('---HD客户端写入结果:isSuccess=$isSuccess,ip=$ip,msgId=${msg?.msgId}');
      //阿里云日志
      XAliyunLogUtils.sendLog(RBAliyunLogUtils.getAliyunLogKey_Print(msg?.orderNo), '---HD客户端写入结果:isSuccess=$isSuccess,ip=$ip,msgId=${msg?.msgId}');

      //打印结果通知
      msg?.isRemoteSocketMessage=false;
      if(!XStringUtils.isEmpty(msg?.orderNo)){

        if(isSuccess){
          if(isEnableServerClientSocketPrint && !isServerSocketPrinter){
            //多端打印子设备,写入成功还需要等主设备打印完毕再通知真正成功
            return;
          }
          _printResult_callback_H5_or_clientSocket(statePage,isSuccess,ip??'',msg);

        }else{
          _printResult_callback_H5_or_clientSocket(statePage,isSuccess,ip??'',msg);
        }
      }
    };
    //
    XSocketUtils.addServerSocketDeviceWriteMessageListener(serverSocketWriteMessageListener);
    XSocketUtils.addClientSocketDeviceWriteMessageListener(clientSocketWriteMessageListener);


    clientSocketDeviceConnectListener=(
        bool isConnect,
        String? ip,
        int? port,
        ){
      if(!isConnect){
        statePage.toast('网络设备:$ip 断开连接');
      }
    };
    XSocketUtils.addClientSocketDeviceConnectListener(clientSocketDeviceConnectListener);

  }



  // static void release(){
  //
  //   XBluetoothBLEUtils.removeWriteMessageToBleDeviceListener(writeMessageToBleDeviceListener);
  //   XBluetoothBLEUtils.removeBleDeviceConnectListener(bleDeviceConnectListener);
  //   XSocketUtils.removeServerSocketDeviceReceiveMessageListener(serverSocketDeviceReceiveMessageListener);
  //   XSocketUtils.removeClientSocketDeviceReceiveMessageListener(clientSocketDeviceReceiveMessageListener);
  //   XSocketUtils.removeServerSocketDeviceWriteMessageListener(serverSocketWriteMessageListener);
  //   XSocketUtils.removeClientSocketDeviceWriteMessageListener(clientSocketWriteMessageListener);
  //   XSocketUtils.removeClientSocketDeviceConnectListener(clientSocketDeviceConnectListener);
  //   msgQueue?.xRelease();
  //
  // }


  static String _jsFunction_notifyPrintEnd(String code,String kmPrintH5Id){
    return "javascript:notifyPrintEnd('$code','$kmPrintH5Id')";
  }




















//快麦云远程api打印//////////////////////////////////////////////////////

// String appID_kuaimai='1625638525787';
// String appSecret_kuaimai='dabef9624c4d4a318cd9843584c2ef1c';
/*
  快麦远程打印,
  sn: 设备序号  KM118MW23230050
  templateId: 模版id
  renderData: 模版动态渲染数据, json字符串
  printTimes:打印份数
   */
// void kuaimaiDeviceApiRemotePrintXiaopian({
//   required String sn,
//   required String templateId,
//   required String renderData,
//   int printTimes=1,
// }){
//
//   String url='https://cloud.kuaimai.com/api/cloud/print/escTemplatePrint';
//   Map<String,dynamic> requestMap={};
//   requestMap['appId']=appID_kuaimai;
//   requestMap['timestamp']=XDateUtils.getCurrentTime_String();
//   requestMap['sn']=sn;
//   requestMap['templateId']=templateId;
//   requestMap['renderData']=renderData;
//   requestMap['cut']=true;
//   requestMap['sign']=_getKuaimaiDeviceApiRemotePrintSign(requestMap);
//
//   XHttpUtils.request_async(
//       url: url,
//       dataJson:XJsonUtils.obj2Json(requestMap),
//       succeed: (String result, Map<String, dynamic> headers_response) {
//
//       },
//       failed: (String code, String msg) {
//
//       }
//   );
//
// }

//获得快麦签名(api远程打印)
// String _getKuaimaiDeviceApiRemotePrintSign(Map<String,dynamic> requestMap){
//   //按升序排序
//   List<String> keys=requestMap.keys.toList();
//   keys.sort();
//   StringBuffer stringBuffer=StringBuffer();
//   //
//   stringBuffer.write(appSecret_kuaimai);
//   //
//   for(String key in keys){
//     stringBuffer.write(key);
//     stringBuffer.write(requestMap[key]);
//   }
//   //
//   stringBuffer.write(appSecret_kuaimai);
//
//   //
//   String x=XJiamiUtils.strToMd5(stringBuffer.toString()).toLowerCase();
//
//   return x;
// }
}